package me.spring.cloud.components.starter.swagger.swagger;

import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.google.common.collect.Lists;
import me.spring.cloud.components.starter.swagger.dynamic.DynamicSwaggerConfiguration;
import me.spring.cloud.components.starter.swagger.properties.SwaggerProperties;
import io.swagger.annotations.Api;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.ApiKey;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger.web.ApiKeyVehicle;

/**
 * @author: luffy
 * @create: 2018-09-12 18:06
 **/
@Configuration
@ConditionalOnProperty(name = SwaggerProperties.prefix + ".enable", havingValue = "true")
@Import(DynamicSwaggerConfiguration.class)
@EnableApolloConfig(DynamicSwaggerConfiguration.namespaces)
public class SwaggerConfiguration {

  @Autowired
  private SwaggerProperties swaggerProperties;

  //TODO 待实现动态切换开启关闭功能

  @Bean
  public Docket createRestApi() {
    List<Parameter> aParameters = new ArrayList<>();
    ParameterBuilder aParameterBuilder = new ParameterBuilder();
    aParameterBuilder.name("Authorization")
        .description("input the token for authentication either in the authorization field or in the token field")
        .modelRef(new ModelRef("string"))
        .parameterType("header")
        .required(false).build();
    aParameters.add(aParameterBuilder.build());
    return new Docket(DocumentationType.SWAGGER_2)
        .enable(swaggerProperties.isEnable())
        .apiInfo(apiInfo())
        .securitySchemes(Lists.newArrayList(apiKey()))
        .globalOperationParameters(aParameters)
        .select()
        .apis(RequestHandlerSelectors.withClassAnnotation(Api.class))
        .paths(PathSelectors.any()).build();
  }

  private ApiInfo apiInfo() {
    return new ApiInfoBuilder()
        .title(swaggerProperties.getTitle())
        .description(swaggerProperties.getDescription())
        .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
        .contact(new Contact("", "", ""))
        .version(swaggerProperties.getVersion())
        .build();
  }

  private ApiKey apiKey() {
    return new ApiKey(swaggerProperties.getApiName(), swaggerProperties.getApiKeyName(),
        ApiKeyVehicle.HEADER.getValue());
  }
}
